from abc import ABC, abstractmethod
from typing import Tuple, Optional
from biz.core.command.handler import Command
from biz.core.command.chain import get_response
from biz.config.settings import Router, get_command_context
from biz.utils.logger import logger
from biz.services.session_service import SessionService
from biz.core.ai.tools import get_prefix


class CommandProcessor(ABC):
    """命令处理器抽象基类"""
    
    @abstractmethod
    def process(self, question: str, uuid: str) -> Tuple[str, str, str]:
        """处理命令"""
        pass


class RouterCommandProcessor(CommandProcessor):
    """路由命令处理器"""
    
    def __init__(self):
        self.command = Command()
        self.vn_command = get_command_context()
        self.router = Router()
    
    def process(self, question: str, uuid: str) -> Tuple[str, str, str]:
        try:
            response = self.vn_command.generate_router(question, self.router.page)
            result = self.command.extract_router(response)
            return uuid, "router", result
        except Exception as e:
            logger.error(f"路由命令处理失败: {e}")
            return uuid, "router", "请求处理失败"


class GeneralCommandProcessor(CommandProcessor):
    """一般命令处理器"""
    
    def __init__(self):
        self.session_service = SessionService()
        self.max_retries = 3
    
    def process(self, question: str, uuid: str) -> Tuple[str, str, str]:
        retry_count = 0
        
        while retry_count < self.max_retries:
            try:
                response_content = self.session_service.invoke_with_history(
                    question=question,
                    uuid=uuid,
                    prefix=get_prefix()
                )
                
                success, result, question = get_response(response_content, '')
                
                if success:
                    return uuid, "command", result
                elif result is not None and result != 'None':
                    return uuid, "command", result
                else:
                    retry_count += 1
                    
            except Exception as e:
                logger.error(f"命令处理失败 (尝试 {retry_count + 1}/{self.max_retries}): {e}")
                retry_count += 1
        
        return uuid, "command", "指令生成错误！"


class CommandFactory:
    """命令工厂类"""
    
    def __init__(self):
        self._processors = {
            'router': RouterCommandProcessor(),
            'general': GeneralCommandProcessor()
        }
        self.command = Command()
    
    def get_processor(self, command_type: Optional[str]) -> CommandProcessor:
        """获取命令处理器"""
        if command_type == 'router':
            return self._processors['router']
        else:
            return self._processors['general']
    
    def generate_uuid(self) -> str:
        """生成新的UUID"""
        return self.command.get_uuid()
    
    def process_command(self, question: str, uuid: Optional[str] = None, command_type: Optional[str] = None) -> Tuple[str, str, str]:
        """处理命令的统一入口"""
        # 生成UUID（如果需要）
        if uuid is None or uuid == '':
            uuid = self.generate_uuid()
        
        # 获取处理器并处理命令
        processor = self.get_processor(command_type)
        return processor.process(question, uuid)